home *** CD-ROM | disk | FTP | other *** search
/ X User Tools / X User Tools (O'Reilly and Associates)(1994).ISO / sources / libxpm / libxpm34.gz / libxpm34 / xpm-3.4 / lib / misc.c < prev    next >
C/C++ Source or Header  |  1994-03-14  |  12KB  |  552 lines

  1. /* Copyright 1989-94 GROUPE BULL -- See license conditions in file COPYRIGHT */
  2. /*****************************************************************************\
  3. * misc.c:                                                                     *
  4. *                                                                             *
  5. *  XPM library                                                               *
  6. *  Miscellaneous utilities                                                    *
  7. *                                                                             *
  8. *  Developed by Arnaud Le Hors                                                *
  9. \*****************************************************************************/
  10.  
  11. #include "xpmP.h"
  12. #ifdef VMS
  13. #include "sys$library:stat.h"
  14. #include "sys$library:fcntl.h"
  15. #else
  16. #include <sys/stat.h>
  17. #include <fcntl.h>
  18. #endif
  19.  
  20. /* 3.2 backward compatibility code */
  21. LFUNC(CreateOldColorTable, int, (XpmColor *ct, int ncolors,
  22.                  XpmColor ***oldct));
  23.  
  24. LFUNC(FreeOldColorTable, void, (XpmColor **colorTable, int ncolors));
  25.  
  26. /*
  27.  * Create a colortable compatible with the old style colortable
  28.  */
  29. static int
  30. CreateOldColorTable(ct, ncolors, oldct)
  31.     XpmColor *ct;
  32.     int ncolors;
  33.     XpmColor ***oldct;
  34. {
  35.     XpmColor **colorTable, **color;
  36.     int a;
  37.  
  38.     colorTable = (XpmColor **) XpmMalloc(ncolors * sizeof(XpmColor *));
  39.     if (!colorTable) {
  40.     *oldct = NULL;
  41.     return (XpmNoMemory);
  42.     }
  43.     for (a = 0, color = colorTable; a < ncolors; a++, color++, ct++)
  44.     *color = ct;
  45.     *oldct = colorTable;
  46.     return (XpmSuccess);
  47. }
  48.  
  49. static void
  50. FreeOldColorTable(colorTable, ncolors)
  51.     XpmColor **colorTable;
  52.     int ncolors;
  53. {
  54.     int a, b;
  55.     XpmColor **color;
  56.     char **sptr;
  57.  
  58.     if (colorTable) {
  59.     for (a = 0, color = colorTable; a < ncolors; a++, color++) {
  60.         for (b = 0, sptr = (char **) *color; b <= NKEYS; b++, sptr++)
  61.         if (*sptr)
  62.             XpmFree(*sptr);
  63.     }
  64.     XpmFree(*colorTable);
  65.     XpmFree(colorTable);
  66.     }
  67. }
  68.  
  69. /* end 3.2 bc */
  70.  
  71.  
  72. /*
  73.  * Free the computed color table
  74.  */
  75. void
  76. xpmFreeColorTable(colorTable, ncolors)
  77.     XpmColor *colorTable;
  78.     int ncolors;
  79. {
  80.     int a, b;
  81.     XpmColor *color;
  82.     char **sptr;
  83.  
  84.     if (colorTable) {
  85.     for (a = 0, color = colorTable; a < ncolors; a++, color++) {
  86.         for (b = 0, sptr = (char **) color; b <= NKEYS; b++, sptr++)
  87.         if (*sptr)
  88.             XpmFree(*sptr);
  89.     }
  90.     XpmFree(colorTable);
  91.     }
  92. }
  93.  
  94. /*
  95.  * Free array of extensions
  96.  */
  97. void
  98. XpmFreeExtensions(extensions, nextensions)
  99.     XpmExtension *extensions;
  100.     int nextensions;
  101. {
  102.     unsigned int i, j, nlines;
  103.     XpmExtension *ext;
  104.     char **sptr;
  105.  
  106.     if (extensions) {
  107.     for (i = 0, ext = extensions; i < nextensions; i++, ext++) {
  108.         if (ext->name)
  109.         XpmFree(ext->name);
  110.         nlines = ext->nlines;
  111.         for (j = 0, sptr = ext->lines; j < nlines; j++, sptr++)
  112.         if (*sptr)
  113.             XpmFree(*sptr);
  114.         if (ext->lines)
  115.         XpmFree(ext->lines);
  116.     }
  117.     XpmFree(extensions);
  118.     }
  119. }
  120.  
  121.  
  122. /*
  123.  * Return the XpmAttributes structure size
  124.  */
  125.  
  126. int 
  127. XpmAttributesSize()
  128. {
  129.     return sizeof(XpmAttributes);
  130. }
  131.  
  132. /*
  133.  * Init returned data to free safely later on
  134.  */
  135. void
  136. xpmInitAttributes(attributes)
  137.     XpmAttributes *attributes;
  138. {
  139.     if (attributes) {
  140.     attributes->pixels = NULL;
  141.     attributes->npixels = 0;
  142.     attributes->colorTable = NULL;
  143.     attributes->ncolors = 0;
  144. /* 3.2 backward compatibility code */
  145.     attributes->hints_cmt = NULL;
  146.     attributes->colors_cmt = NULL;
  147.     attributes->pixels_cmt = NULL;
  148. /* end 3.2 bc */
  149.     attributes->extensions = NULL;
  150.     attributes->nextensions = 0;
  151.     }
  152. }
  153.  
  154. /*
  155.  * Fill in the XpmAttributes with the XpmImage and the XpmInfo
  156.  */
  157. void
  158. xpmSetAttributes(attributes, image, info)
  159.     XpmAttributes *attributes;
  160.     XpmImage *image;
  161.     XpmInfo *info;
  162. {
  163.     if (attributes->valuemask & XpmReturnColorTable) {
  164.     attributes->colorTable = image->colorTable;
  165.     attributes->ncolors = image->ncolors;
  166.  
  167.     /* avoid deletion of copied data */
  168.     image->ncolors = 0;
  169.     image->colorTable = NULL;
  170.     }
  171. /* 3.2 backward compatibility code */
  172.     else if (attributes->valuemask & XpmReturnInfos) {
  173.     int ErrorStatus;
  174.  
  175.     ErrorStatus = CreateOldColorTable(image->colorTable, image->ncolors,
  176.                       (XpmColor ***)
  177.                       &attributes->colorTable);
  178.  
  179.     /* if error just say we can't return requested data */
  180.     if (ErrorStatus != XpmSuccess) {
  181.         attributes->valuemask &= ~XpmReturnInfos;
  182.         if (!(attributes->valuemask & XpmReturnPixels)) {
  183.         XpmFree(attributes->pixels);
  184.         attributes->pixels = NULL;
  185.         attributes->npixels = 0;
  186.         }
  187.         attributes->ncolors = 0;
  188.     } else {
  189.         attributes->ncolors = image->ncolors;
  190.         attributes->hints_cmt = info->hints_cmt;
  191.         attributes->colors_cmt = info->colors_cmt;
  192.         attributes->pixels_cmt = info->pixels_cmt;
  193.  
  194.         /* avoid deletion of copied data */
  195.         image->ncolors = 0;
  196.         image->colorTable = NULL;
  197.         info->hints_cmt = NULL;
  198.         info->colors_cmt = NULL;
  199.         info->pixels_cmt = NULL;
  200.     }
  201.     }
  202. /* end 3.2 bc */
  203.     if (attributes->valuemask & XpmReturnExtensions) {
  204.     attributes->extensions = info->extensions;
  205.     attributes->nextensions = info->nextensions;
  206.  
  207.     /* avoid deletion of copied data */
  208.     info->extensions = NULL;
  209.     info->nextensions = 0;
  210.     }
  211.     if (info->valuemask & XpmHotspot) {
  212.     attributes->valuemask |= XpmHotspot;
  213.     attributes->x_hotspot = info->x_hotspot;
  214.     attributes->y_hotspot = info->y_hotspot;
  215.     }
  216.     attributes->valuemask |= XpmCharsPerPixel;
  217.     attributes->cpp = image->cpp;
  218.     attributes->valuemask |= XpmSize;
  219.     attributes->width = image->width;
  220.     attributes->height = image->height;
  221. }
  222.  
  223. /*
  224.  * Free the XpmAttributes structure members
  225.  * but the structure itself
  226.  */
  227. void
  228. XpmFreeAttributes(attributes)
  229.     XpmAttributes *attributes;
  230. {
  231.     if (attributes->valuemask & XpmReturnPixels && attributes->npixels) {
  232.     XpmFree(attributes->pixels);
  233.     attributes->pixels = NULL;
  234.     attributes->npixels = 0;
  235.     }
  236.     if (attributes->valuemask & XpmReturnColorTable) {
  237.     xpmFreeColorTable(attributes->colorTable, attributes->ncolors);
  238.     attributes->colorTable = NULL;
  239.     attributes->ncolors = 0;
  240.     }
  241. /* 3.2 backward compatibility code */
  242.     else if (attributes->valuemask & XpmInfos) {
  243.     if (attributes->colorTable) {
  244.         FreeOldColorTable((XpmColor **) attributes->colorTable,
  245.                   attributes->ncolors);
  246.         attributes->colorTable = NULL;
  247.         attributes->ncolors = 0;
  248.     }
  249.     if (attributes->hints_cmt) {
  250.         XpmFree(attributes->hints_cmt);
  251.         attributes->hints_cmt = NULL;
  252.     }
  253.     if (attributes->colors_cmt) {
  254.         XpmFree(attributes->colors_cmt);
  255.         attributes->colors_cmt = NULL;
  256.     }
  257.     if (attributes->pixels_cmt) {
  258.         XpmFree(attributes->pixels_cmt);
  259.         attributes->pixels_cmt = NULL;
  260.     }
  261.     if (attributes->pixels) {
  262.         XpmFree(attributes->pixels);
  263.         attributes->pixels = NULL;
  264.         attributes->npixels = 0;
  265.     }
  266.     }
  267. /* end 3.2 bc */
  268.     if (attributes->valuemask & XpmReturnExtensions
  269.     && attributes->nextensions) {
  270.     XpmFreeExtensions(attributes->extensions, attributes->nextensions);
  271.     attributes->extensions = NULL;
  272.     attributes->nextensions = 0;
  273.     }
  274.     attributes->valuemask = 0;
  275. }
  276.  
  277. /*
  278.  * Init returned data to free safely later on
  279.  */
  280. void
  281. xpmInitXpmImage(image)
  282.     XpmImage *image;
  283. {
  284.     image->ncolors = 0;
  285.     image->colorTable = NULL;
  286.     image->data = NULL;
  287. }
  288.  
  289. /*
  290.  * Free the XpmImage data which have been allocated
  291.  */
  292. void
  293. XpmFreeXpmImage(image)
  294.     XpmImage *image;
  295. {
  296.     if (image->colorTable)
  297.     xpmFreeColorTable(image->colorTable, image->ncolors);
  298.     XpmFree(image->data);
  299.     image->data = NULL;
  300. }
  301.  
  302. /*
  303.  * Init returned data to free safely later on
  304.  */
  305. void
  306. xpmInitXpmInfo(info)
  307.     XpmInfo *info;
  308. {
  309.     if (info) {
  310.     info->hints_cmt = NULL;
  311.     info->colors_cmt = NULL;
  312.     info->pixels_cmt = NULL;
  313.     info->extensions = NULL;
  314.     info->nextensions = 0;
  315.     }
  316. }
  317.  
  318. /*
  319.  * Free the XpmInfo data which have been allocated
  320.  */
  321. void
  322. XpmFreeXpmInfo(info)
  323.     XpmInfo *info;
  324. {
  325.     if (info) {
  326.     if (info->valuemask & XpmComments) {
  327.         if (info->hints_cmt) {
  328.         XpmFree(info->hints_cmt);
  329.         info->hints_cmt = NULL;
  330.         }
  331.         if (info->colors_cmt) {
  332.         XpmFree(info->colors_cmt);
  333.         info->colors_cmt = NULL;
  334.         }
  335.         if (info->pixels_cmt) {
  336.         XpmFree(info->pixels_cmt);
  337.         info->pixels_cmt = NULL;
  338.         }
  339.     }
  340.     if (info->valuemask & XpmReturnExtensions && info->nextensions) {
  341.         XpmFreeExtensions(info->extensions, info->nextensions);
  342.         info->extensions = NULL;
  343.         info->nextensions = 0;
  344.     }
  345.     info->valuemask = 0;
  346.     }
  347. }
  348.  
  349. /*
  350.  * Set the XpmInfo valuemask to retrieve required info
  351.  */
  352. void
  353. xpmSetInfoMask(info, attributes)
  354.     XpmInfo *info;
  355.     XpmAttributes *attributes;
  356. {
  357.     info->valuemask = 0;
  358.     if (attributes->valuemask & XpmReturnInfos)
  359.     info->valuemask |= XpmReturnComments;
  360.     if (attributes->valuemask & XpmReturnExtensions)
  361.     info->valuemask |= XpmReturnExtensions;
  362. }
  363.  
  364. /*
  365.  * Fill in the XpmInfo with the XpmAttributes
  366.  */
  367. void
  368. xpmSetInfo(info, attributes)
  369.     XpmInfo *info;
  370.     XpmAttributes *attributes;
  371. {
  372.     info->valuemask = 0;
  373.     if (attributes->valuemask & XpmInfos) {
  374.     info->valuemask |= XpmComments | XpmColorTable;
  375.     info->hints_cmt = attributes->hints_cmt;
  376.     info->colors_cmt = attributes->colors_cmt;
  377.     info->pixels_cmt = attributes->pixels_cmt;
  378.     }
  379.     if (attributes->valuemask & XpmExtensions) {
  380.     info->valuemask |= XpmExtensions;
  381.     info->extensions = attributes->extensions;
  382.     info->nextensions = attributes->nextensions;
  383.     }
  384.     if (attributes->valuemask & XpmHotspot) {
  385.     info->valuemask |= XpmHotspot;
  386.     info->x_hotspot = attributes->x_hotspot;
  387.     info->y_hotspot = attributes->y_hotspot;
  388.     }
  389. }
  390.  
  391.  
  392. #ifdef NEED_STRDUP
  393. /*
  394.  * in case strdup is not provided by the system here is one
  395.  * which does the trick
  396.  */
  397. char *
  398. strdup(s1)
  399.     char *s1;
  400. {
  401.     char *s2;
  402.     int l = strlen(s1) + 1;
  403.  
  404.     if (s2 = (char *) XpmMalloc(l))
  405.     strncpy(s2, s1, l);
  406.     return s2;
  407. }
  408.  
  409. #endif
  410.  
  411. /*
  412.  *  File / Buffer utilities
  413.  */
  414. int
  415. XpmReadFileToBuffer(filename, buffer_return)
  416.     char *filename;
  417.     char **buffer_return;
  418. {
  419.     int fd, fcheck, len;
  420.     char *ptr;
  421.     struct stat stats;
  422.     FILE *fp;
  423.  
  424.     *buffer_return = NULL;
  425.  
  426.     fd = open(filename, O_RDONLY);
  427.     if (fd < 0)
  428.     return XpmOpenFailed;
  429.  
  430.     if (fstat(fd, &stats)) {
  431.     close(fd);
  432.     return XpmOpenFailed;
  433.     }
  434.     fp = fdopen(fd, "r");
  435.     if (!fp) {
  436.     close(fd);
  437.     return XpmOpenFailed;
  438.     }
  439.     len = (int) stats.st_size;
  440.     ptr = (char *) XpmMalloc(len + 1);
  441.     if (!ptr) {
  442.     fclose(fp);
  443.     return XpmNoMemory;
  444.     }
  445.     fcheck = fread(ptr, len, 1, fp);
  446.     fclose(fp);
  447.     if (fcheck != 1) {
  448.     XpmFree(ptr);
  449.     return XpmOpenFailed;
  450.     }
  451.     ptr[len] = '\0';
  452.     *buffer_return = ptr;
  453.     return XpmSuccess;
  454. }
  455.  
  456. int
  457. XpmWriteFileFromBuffer(filename, buffer)
  458.     char *filename;
  459.     char *buffer;
  460. {
  461.     int fcheck, len;
  462.     FILE *fp = fopen(filename, "w");
  463.  
  464.     if (!fp)
  465.     return XpmOpenFailed;
  466.  
  467.     len = strlen(buffer);
  468.     fcheck = fwrite(buffer, len, 1, fp);
  469.     fclose(fp);
  470.     if (fcheck != 1)
  471.     return XpmOpenFailed;
  472.  
  473.     return XpmSuccess;
  474. }
  475.  
  476.  
  477. /*
  478.  * Small utility function
  479.  */
  480. char *
  481. XpmGetErrorString(errcode)
  482.     int errcode;
  483. {
  484.     switch (errcode) {
  485.     case XpmColorError:
  486.     return ("XpmColorError");
  487.     case XpmSuccess:
  488.     return ("XpmSuccess");
  489.     case XpmOpenFailed:
  490.     return ("XpmOpenFailed");
  491.     case XpmFileInvalid:
  492.     return ("XpmFileInvalid");
  493.     case XpmNoMemory:
  494.     return ("XpmNoMemory");
  495.     case XpmColorFailed:
  496.     return ("XpmColorFailed");
  497.     default:
  498.     return ("Invalid XpmError");
  499.     }
  500. }
  501.  
  502. /*
  503.  * The following function provides a way to figure out if the linked library is
  504.  * newer or older than the one with which a program has been first compiled.
  505.  */
  506. int
  507. XpmLibraryVersion()
  508. {
  509.     return XpmIncludeVersion;
  510. }
  511.  
  512.  
  513.  
  514. void
  515. xpmCreatePixmapFromImage(display, d, ximage, pixmap_return)
  516.     Display *display;
  517.     Drawable d;
  518.     XImage *ximage;
  519.     Pixmap *pixmap_return;
  520. {
  521.     GC gc;
  522.  
  523.     *pixmap_return = XCreatePixmap(display, d, ximage->width,
  524.                    ximage->height, ximage->depth);
  525.     gc = XCreateGC(display, *pixmap_return, 0, NULL);
  526.  
  527.     XPutImage(display, *pixmap_return, gc, ximage, 0, 0, 0, 0,
  528.           ximage->width, ximage->height);
  529.  
  530.     XFreeGC(display, gc);
  531. }
  532.  
  533. void
  534. xpmCreateImageFromPixmap(display, pixmap, ximage_return, width, height)
  535.     Display *display;
  536.     Pixmap pixmap;
  537.     XImage **ximage_return;
  538.     unsigned int *width;
  539.     unsigned int *height;
  540. {
  541.     unsigned int dum;
  542.     int dummy;
  543.     Window win;
  544.  
  545.     if (*width == 0 && *height == 0)
  546.     XGetGeometry(display, pixmap, &win, &dummy, &dummy,
  547.              width, height, &dum, &dum);
  548.  
  549.     *ximage_return = XGetImage(display, pixmap, 0, 0, *width, *height,
  550.                    AllPlanes, ZPixmap);
  551. }
  552.